package org.xlp.db.sql;

import org.xlp.db.exception.EntityException;
import org.xlp.db.sql.limit.Limit;
import org.xlp.db.utils.SQLUtil;

/**
 * Description: 分页查询抽象类
 * <br/>date: 2024/1/15 22:48
 *
 * @version 1.0
 * @author: xlp
 */
public abstract class AbstractPagedSQL<T> extends QuerySQL<T> implements PagedSQL{
    /**
     * 标记是否自动创建countSql，默认自动创建
     */
    private boolean autoCreateCountSql = true;

    /**
     * 分页查询信息
     */
    protected Limit limit;

    /**
     * 构造函数
     * @param beanClass
     * @throws EntityException
     */
    public AbstractPagedSQL(Class<T> beanClass) throws EntityException {
        super(beanClass);
    }

    /***
     * 构造函数
     * @param beanClass
     * @param startPos
     * @param resultCount
     * @throws EntityException
     */
    public AbstractPagedSQL(Class<T> beanClass, long startPos, long resultCount)
            throws EntityException {
        super(beanClass);
        this.limit = new Limit(startPos, resultCount);
    }

    /**
     * 设置分页信息
     * @param limit
     * @return
     */
    public AbstractPagedSQL<T> limit(Limit limit){
        this.limit = limit;
        return this;
    }

    /**
     * 设置分页信息
     *
     * @param limit
     */
    @Override
    public void setLimit(Limit limit) {
        limit(limit);
    }

    @Override
    public Limit getLimit() {
        return limit;
    }

    @Override
    public String getSql() {
        StringBuilder sb = new StringBuilder(getParamSql());
        return SQLUtil.fillWithParams(sb, getParams());
    }

    protected Object[] getNotLimitParams(){
        return super.getParams();
    }

    public boolean isAutoCreateCountSql() {
        return autoCreateCountSql;
    }

    /**
     * 标记是否自动创建countSql，true: 自动创建， false：不创建
     */
    public void setAutoCreateCountSql(boolean autoCreateCountSql) {
        this.autoCreateCountSql = autoCreateCountSql;
    }

    /**
     * 获取总数据条数SQL对象
     *
     * @return
     */
    @Override
    public Statistics countSql() {
        if (!autoCreateCountSql) return null;

        SQL querySQL = this;
        return new Statistics() {
            @Override
            public String getSql() {
                StringBuilder sb = new StringBuilder(getParamSql());
                return SQLUtil.fillWithParams(sb, getParams());
            }

            @Override
            public String getParamSql() {
                StringBuilder sb = new StringBuilder();
                String tableAlias = SQLUtil.getTableAlias(getTable());
                if (isDistinct()){
                    sb.append("select count(*) from (");
                    sb.append(preSql());
                } else {
                    sb.append("select count(*) from ");
                    sb.append(getTable().getTableName()).append(" ")
                            .append(tableAlias.isEmpty() ? tableAlias : tableAlias.substring(0, tableAlias.length() - 1))
                            .append(" ");
                }
                //拼接条件
                String condition = formatterConditionSql();
                if (!condition.isEmpty()) {
                    sb.append("where ").append(condition);
                }

                //拼接group by
                if (!groupFields.isEmpty()) {
                    sb.append(" group by ");
                    boolean start = true;
                    for (String group : groupFields) {
                        if (!start) {
                            sb.append(COMMA).append(" ");
                        }
                        sb.append(tableAlias).append(group);
                        start = false;
                    }
                }
                if (isDistinct()){
                    sb.append(")");
                }
                return sb.toString();
            }

            @Override
            public Object[] getParams() {
                return getNotLimitParams();
            }

            @Override
            public Class<?> getEntityClass() {
                return querySQL.getEntityClass();
            }
        };
    }
}
